#include "ButtonWidget.h"
#include "Font/FontSubsystem.h"
#include "Render/Widget/RenderWidgets.h"

RButtonWidget::RButtonWidget()
{
    MouseWidget=NewWidget<RMouseWidget>(this);
    MouseWidget->Anchor.Fill(this);

    MouseWidget->OnClicked.Bind(this,&RButtonWidget::NotifyOnClicked);
    MouseWidget->OnDoubleClicked.Bind(this,&RButtonWidget::NotifyOnDoubleClicked);
    MouseWidget->OnPressed.Bind(this,&RButtonWidget::NotifyOnPressed);
    MouseWidget->OnReleased.Bind(this,&RButtonWidget::NotifyOnReleased);

    MouseWidget->OnEntered.Bind(this,&RButtonWidget::OnHovered);
    MouseWidget->OnExited.Bind(this,&RButtonWidget::OnUnhovered);
}

void RButtonWidget::SetHovorColor(SColor InColor, SColor InHorveredColor)
{
    BackgroundStyle.FillColor=
    [this,InColor,InHorveredColor]()
    {
        if(bIsHovered)
        {
            return InHorveredColor;
        }
        else
        {
            return InColor;
        }
    };

}

bool RButtonWidget::IsPressed()
{
    return bIsPressed;
}

bool RButtonWidget::IsHovered()
{
    return bIsHovered;
}

SVec2 RButtonWidget::GetTextSize()
{
    return TextArranger.GetArrangeResult().CalculateTextSize();
}

bool RButtonWidget::NotifyOnClicked(const SMouseButtonEvent &MouseEvent)
{
    return OnClicked.Broadcast(MouseEvent);
}

bool RButtonWidget::NotifyOnDoubleClicked(const SMouseButtonEvent& MouseEvent)
{
    return OnDoubleClicked.Broadcast(MouseEvent);
}

bool RButtonWidget::NotifyOnPressed(const SMouseButtonEvent& MouseEvent)
{
    bIsPressed=true;
    return OnPressed.Broadcast(MouseEvent);
}

bool RButtonWidget::NotifyOnReleased(const SMouseButtonEvent& MouseEvent)
{
    bIsPressed=false;
    return OnReleased.Broadcast(MouseEvent);
}

void RButtonWidget::OnHovered()
{
    bIsHovered=true;
}

void RButtonWidget::OnUnhovered()
{
    bIsHovered=false;
}

void RButtonWidget::PaintSelf(uint16_t& InZOrder,const SRect& InClipArea)
{
    auto BackgroundRenderWidget=std::make_shared<SRenderRectWidget>();


    //paint background
    {
        BackgroundRenderWidget->bFill=BackgroundStyle.Fill.Get();
        BackgroundRenderWidget->FillColor=BackgroundStyle.FillColor.Get();
        BackgroundRenderWidget->BorderColor=BackgroundStyle.BorderColor.Get();
        BackgroundRenderWidget->BorderSize=BackgroundStyle.BorderSize.Get();
        BackgroundRenderWidget->ZOrder=InZOrder;
        BackgroundRenderWidget->Radius=BackgroundStyle.CornerRadius.Get();
        InZOrder++;
        BackgroundRenderWidget->Rect=SRect(PresentAbsPosition,PresentSize);
        BackgroundRenderWidget->ClipRect=InClipArea;

        PaintRenderWidget(BackgroundRenderWidget);
    }

    //Arrange text
    CString _Text=Text.Get();
    float TextWidth=0;
    float FontSize=TextStyle.FontSize.Get();
    RFontPtr Font=TextStyle.Font.Get();
    bool bHasValidText=!_Text.IsEmpty() && FontSize>0;
    if(!Font && bHasValidText)
    {
        Font=RFontApplicationSubsystem::Get()->GetDefaultFont();
    }

    if(bHasValidText)
    {
        TextWidth=RFontApplicationSubsystem::Get()->GetOccupiedSize(
            _Text
            ,Font
            ,FontSize
        ).X;
    }

     
    //绘制icon
    float TextLeftOffset=0;
    auto IconTexture=Icon.Texture.Get();
    if(IconTexture.IsValid())
    {    
        SVec2 IconSize=SVec2(Icon.Width.Get(),Icon.Height.Get());
        SVec2 IconPosition;
        IconPosition.Y=PresentAbsPosition.Y+(PresentSize.Y-IconSize.Y)/2;
        if(!bHasValidText)
        {
            IconPosition.X=PresentAbsPosition.X+(PresentSize.X-IconSize.X)/2;
        }
        else
        {
            TextLeftOffset=IconSize.X+IconTextDistance;
            IconPosition.X=PresentAbsPosition.X+(PresentSize.X-IconSize.X-TextWidth-IconTextDistance)/2;
        }

        
        auto IconClipArea=InClipArea.Intersect(SRect(IconPosition,IconSize));

        if(IconClipArea.HasValue())
        {
            auto IconRenderWidget=std::make_shared<SRenderImageWidget>();
            IconRenderWidget->ClipRect=IconClipArea.GetValue();
            IconRenderWidget->Rect=SRect(IconPosition,IconSize);
            IconRenderWidget->Image=IconTexture->GetRenderTexture();
            IconRenderWidget->ZOrder=InZOrder;
            InZOrder++;

            PaintRenderWidget(IconRenderWidget);                    
        }
    }

    //绘制文字
    if(bHasValidText)
    {
        STextArrangePapameters Params;
        Params.Font=Font;
        Params.FontSize=FontSize;
        Params.Text=_Text;
        Params.VerticalAlign=ETextVerticalAlignment::Center;

        if(!IconTexture.IsValid())
        {
            Params.PaintAreaSize=PresentSize;
            Params.HorizontalAlign=ETextHorizontalAlignment::Center;
        }
        else
        {
            //Params.PaintArea.Min=SVec2(TextLeftOffset+PresentAbsPosition.X,PresentAbsPosition.Y)  ;
            Params.PaintAreaSize=SVec2(PresentSize.X-TextLeftOffset,PresentSize.Y);
            Params.HorizontalAlign=ETextHorizontalAlignment::Left;
        }


        TextArranger.ArrangeText(Params);

        // auto RenderTextWidget=std::make_shared<SRenderStaticTextWidget>();

        // RenderTextWidget->Rect= SRect(
        //     SVec2(TextArranger.GetArrangeResult().WholeImageOffset.X+PresentAbsPosition.X+TextLeftOffset
        //     ,TextArranger.GetArrangeResult().WholeImageOffset.Y+PresentAbsPosition.Y)
        //     ,TextArranger.GetArrangeResult().WholeImageSize
        // );
        // RenderTextWidget->ClipRect=InClipArea;
        // RenderTextWidget->ZOrder=InZOrder;
        // InZOrder++;

        // RenderTextWidget->TextImage=TextArranger.GetArrangeResult().WholeImage->GetRenderTexture();
        // RenderTextWidget->TextColor=TextStyle.Color.Get();

        auto RenderTextWidget=std::make_shared<SRenderStaticTextWidget>();
        RenderTextWidget->Rect=SRect(SVec2(
            PresentAbsPosition.X+TextLeftOffset,PresentAbsPosition.Y)
            ,PresentSize);
        RenderTextWidget->ClipRect=InClipArea;
        RenderTextWidget->ZOrder=InZOrder;
        InZOrder++;

        RenderTextWidget->TextColor= TextStyle.Color.Get();
        RenderTextWidget->CharTextures=TextArranger.GetArrangeResult().GetRenderCharTextures();
        RenderTextWidget->CharPositions=TextArranger.GetArrangeResult().GetCharPositions();


        PaintRenderWidget(RenderTextWidget);  
    }

}


